﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace CollisionDetectionSandbox
{
    public class Special
    {
        
        public ElementType Type { get; set; }
        public Vector2 Location { get; set; }
        //public float Slope { get; set; }
        public float Rotation { get; set; }
        public Vector2 Size { get { return SIZE; } }
        private Vector2 StartLocation { get; set; }

        public float Left { get { return Location.X - (Size.X / 2f); } }
        public float Right { get { return Location.X + (Size.X / 2f); } }
        public float Top { get { return Location.Y - (Size.Y / 2f); } }
        public float Bottom { get { return Location.Y + (Size.Y / 2f); } }

        private readonly Vector2 SIZE = new Vector2(10, 50);
        private const float BULLET_SPEED = 5;//pixels per update

        public static List<Special> ObjectList = new List<Special>();

        public Special(ElementType type, Vector2 location)
        {
            Type = type;
            Rotation = MathHelper.PiOver2;
            Location = location;
            StartLocation = location;
            GameScreen.ZeusThrowInstance.Volume = 0.4f;
            GameScreen.ZeusThrowInstance.Play();
        }

        public static void SpawnWave(ElementType type)
        {
            float x = 40 / 2f + 120;

            while (x <= GameScreen.GAME_WIDTH - (40 / 2f) - 110)
            {
                Vector2 loc = new Vector2(x, 500);

               

                Special s = new Special(type, loc);
                ObjectList.Add(s);

                x += 40;
            }
        }

        public void MoveOneStep()
        {
            float slope = (float)Math.Tan(Rotation);

            //get unit vector in direction of bullet travel
            Vector2 unit = new Vector2();
            if (slope < 0)
            {
                unit = new Vector2(-1, -slope);
            }
            else
            {
                unit = new Vector2(1, slope);
            }

            unit.Normalize();

            //multiply by bullet speed
            unit = new Vector2(unit.X * BULLET_SPEED, unit.Y * BULLET_SPEED);
            //add to current location
            Location = new Vector2(Location.X + unit.X, Location.Y - unit.Y);
        }

        public bool IsOffScreen()
        {
            bool bOffScreen = false;

            bOffScreen |= (this.Left > GameScreen.GAME_WIDTH - 120);
            bOffScreen |= (this.Right < 120);
            bOffScreen |= (this.Top > GameScreen.GAME_HEIGHT);
            bOffScreen |= (this.Bottom < 0);

            return bOffScreen;
        }

        public void Delete()
        {
            ObjectList.Remove(this);
        }

        public List<Enemy> GetEnemiesHit()
        {
            List<Enemy> hit = new List<Enemy>();

            foreach (Enemy e in Enemy.ObjectList)
            {
                Vector3 enemyloc = new Vector3(e.Location.X, e.Location.Y, 0);
                BoundingSphere enemysphere = new BoundingSphere(enemyloc, e.Size.X / 2);

                Vector2 dir = Location - StartLocation;
                dir.Normalize();

                Ray upRay = new Ray(new Vector3(Location, 0), new Vector3(dir, 0));
                float? rVal = upRay.Intersects(enemysphere);

                if (rVal.HasValue && Math.Abs(rVal.Value) <= (Size.Y / 2))
                {
                    if (this.DoesKill(e))
                    {
                        switch (e.Type)
                        {
                            case ElementType.Fire:
                                GameScreen.fireExplodeInstance.Play();
                                break;
                            case ElementType.Earth:
                                GameScreen.earthExplodeInstance.Volume = .1f;
                                GameScreen.earthExplode.Play();
                                break;
                            case ElementType.Lightning:
                                GameScreen.lightningExplodeInstance.Volume = .1f;
                                GameScreen.lightningExplode.Play();
                                break;
                            case ElementType.Water:
                                GameScreen.waterExplodeInstance.Volume = .1f;
                                GameScreen.waterExplode.Play();
                                break;
                        }
                        //this projectile kills this enemy
                        hit.Add(e);
                    }
                }
            }

            return hit;
        }

        private bool DoesKill(Enemy e)
        {
            bool bKills = false;

            switch (this.Type)
            {
                case ElementType.Fire:
                    bKills = (e.Type == ElementType.Earth);
                    break;
                case ElementType.Earth:
                    bKills = (e.Type == ElementType.Lightning);
                    break;
                case ElementType.Water:
                    bKills = (e.Type == ElementType.Fire);
                    break;
                case ElementType.Lightning:
                    bKills = (e.Type == ElementType.Water);
                    break;
                default:
                    break;
            }

            return bKills;
        }

        public void Draw(SpriteBatch batch)
        {
            Texture2D texture;

            switch (Type)
            {
                case ElementType.Fire:
                    texture = GameScreen.BulletFireTexture;
                    break;
                case ElementType.Earth:
                    texture = GameScreen.BulletEarthTexture;
                    break;
                case ElementType.Water:
                    texture = GameScreen.BulletWaterTexture;
                    break;
                default:
                    texture = GameScreen.BulletLightTexture;

                    break;
            }

            //it wants the top left corner for location, not the center
            Vector2 drawLoc = new Vector2(Left, Top);
            batch.Draw(texture, Location, null, Color.White, MathHelper.PiOver2 - Rotation, (Location - drawLoc), 1f, SpriteEffects.None, 0);
        }
    }
}
